# -*- coding: utf-8 -*-
# @Time    : 2024/6/6 10:26
# @Author  : yujiahao
# @File    : 06_str_method.py
# @description:再看字符串，字符串处理是世界难题，同志们要加油！


'''
字符串, 用于存储一些少量的数据,在Pyhton当中只要是用引号引起来的就是字符串,字符串中的每个单独的字母汉字都是一个元素.
在前面咱们简单的认识了下字符串,今天我们好好的来认识一下这个让你又喜又优的字符串
我们来回忆下字符串是不是可以进行加减乘除
'''


# todo 1、 字符串加
a = '世界\t'
b = '你好'
print(a + b)


'''通过刚刚我们的测试发现字符串也是可以进行加法操作的,字符串相加其实有个专业的名词 --- 字符串拼接;
相加的规则就是必须都是字符串才能相加字符串中是不能进行减法和除法操作的,通过这句话就能得知字符串是可以进行乘法操作的,
字符串的乘法就是将多个字符串拼接到一起,乘法的规则:只能是字符串和数字相乘
我们立马来看一下:
'''

# todo 2、 字符串乘
a = '坚强\t'
print(a * 8)



# todo 3、 索引(下标)
'''
大家在上学的时候就会发现在一个班有的同学的名字是一样的,最后大家为了好区分就有了外号,我们每个人都有个学号,其实学校就是为了防止重名找错人,
学号就是一种能够保证唯一且准确的手段,这种手段在计算机中存在,这种手段叫做索引,也有人称之为下标（角标）.
    ① 从左到右：
        name        =        "yujiahao"
         |          |         ||||||||
       变量名     赋值符号      01234567 （从左侧开始，索引从0开始）

这个结构大家前面说过了，赋值操作，主要看字符串的索引起始是从左到右从0开始+1是整数值，当然也可以是负值从右到左起始值从-1开始，依次-1：
    
    ② 从右到左：
        name        =        "yujiahao"
         |          |         ||||||||
       变量名     赋值符号      -8  ~~ -1（从右侧开始，索引从-1开始，方便观看中间省略了）

如何根据索引找对应的值，那么下面来看：
'''

name = 'yujiahao'
print(f'找出索引为1的字符：{name[1]}')
print(f'找出索引为-8的字符：{name[-8]}')

# todo 4、切片

# 这个前面都讲过了，这里就看一下，注意切片是左闭右开,写法是：[开始索引：结束索引：步长]，实际上应该是这么理解：[起始索引：结束索引：步长 ）
print(f'我是切片：{name[:5]}')


# todo 5、字符串方法

"""
Python、Java 和 Scala 字符串方法对比:

Python 字符串方法示例:
    
    name = 'yujiahao'

    1. 大写转换
    示例:
    name.upper()  # 'YUJIAHAO'
    
    2. 小写转换
    示例:
    name.lower()  # 'yujiahao'
    
    3. 首字母大写
    示例:
    name.capitalize()  # 'Yujiahao'
    
    4. 标题化（每个单词首字母大写）
    示例:
    name.title()  # 'Yujiahao'
    
    5. 去除两端空白
    示例:
    name.strip()  # 'yujiahao'
    
    6. 替换字符串
    示例:
    name.replace('yu', 'Yu')  # 'Yujiahao'
    
    7. 查找子字符串
    示例:
    name.find('jia')  # 2
    
    8. 分割字符串
    示例:
    name.split('j')  # ['yu', 'iahao']
    
    9. 拼接字符串
    示例:
    '_'.join(['yu', 'jiahao'])  # 'yu_jiahao'
    
    10. 检查前缀
    示例:
    name.startswith('yu')  # True
    
    11. 检查后缀
    示例:
    name.endswith('hao')  # True
    
    12.使用for、while打印
    
    for i in name:
        print(i)
        
    count = 0
    while count < len(name):
        print(name[count])
        count = count + 1


Java 字符串方法示例:
    String name = "yujiahao";
    
        1. 大写转换
        示例:
        name.toUpperCase()  # "YUJIAHAO"
        
        2. 小写转换
        示例:
        name.toLowerCase()  # "yujiahao"
        
        3. 首字母大写
        示例:
        Character.toUpperCase(name.charAt(0)) + name.substring(1)  # "Yujiahao"
        
        4. 标题化（每个单词首字母大写）
        示例:
        // Java 没有内置的标题化方法，需要手动实现
        String[] words = name.split(" ");
        StringBuilder titleCase = new StringBuilder();
        for (String word : words) {
            titleCase.append(Character.toUpperCase(word.charAt(0))).append(word.substring(1)).append(" ");
        }
        titleCase.toString().trim();  # "Yujiahao"
        
        5. 去除两端空白
        示例:
        name.trim()  # "yujiahao"
        
        6. 替换字符串
        示例:
        name.replace("yu", "Yu")  # "Yujiahao"
        
        7. 查找子字符串
        示例:
        name.indexOf("jia")  # 2
        
        8. 分割字符串
        示例:
        name.split("j")  # ["yu", "iahao"]
        
        9. 拼接字符串
        示例:
        String.join("_", "yu", "jiahao")  # "yu_jiahao"
        
        10. 检查前缀
        示例:
        name.startsWith("yu")  # true
        
        11. 检查后缀
        示例:
        name.endsWith("hao")  # true


Scala 字符串方法示例:
    val name = "yujiahao"
    
        1. 大写转换
        示例:
        name.toUpperCase  # "YUJIAHAO"
        
        2. 小写转换
        示例:
        name.toLowerCase  # "yujiahao"
        
        3. 首字母大写
        示例:
        name.capitalize  # "Yujiahao"
        
        4. 标题化（每个单词首字母大写）
        示例:
        // Scala 没有内置的标题化方法，需要手动实现
        name.split(" ").map(_.capitalize).mkString(" ")  # "Yujiahao"
        
        5. 去除两端空白
        示例:
        name.trim  # "yujiahao"
        
        6. 替换字符串
        示例:
        name.replace("yu", "Yu")  # "Yujiahao"
        
        7. 查找子字符串
        示例:
        name.indexOf("jia")  # 2
        
        8. 分割字符串
        示例:
        name.split("j")  # Array("yu", "iahao")
        
        9. 拼接字符串
        示例:
        Array("yu", "jiahao").mkString("_")  # "yu_jiahao"
        
        10. 检查前缀
        示例:
        name.startsWith("yu")  # true
        
        11. 检查后缀
        示例:
        name.endsWith("hao")  # true
"""



# 大写转换
print(f"{name.upper()} - 方法: 大写转换")  # 打印: 'YUJIAHAO - 方法: 大写转换'

# 小写转换
print(f"{name.lower()} - 方法: 小写转换")  # 打印: 'yujiahao - 方法: 小写转换'

# 首字母大写
print(f"{name.capitalize()} - 方法: 首字母大写")  # 打印: 'Yujiahao - 方法: 首字母大写'

# 标题化（每个单词首字母大写）
print(f"{name.title()} - 方法: 标题化")  # 打印: 'Yujiahao - 方法: 标题化'

# 去除两端空白
print(f"{name.strip()} - 方法: 去除两端空白")  # 打印: 'yujiahao - 方法: 去除两端空白'

# 替换字符串
print(f"{name.replace('yu', 'Yu')} - 方法: 替换字符串")  # 打印: 'Yujiahao - 方法: 替换字符串'

# 查找子字符串
# 查找子字符串在字符串中的首次出现位置。如果找到子字符串，则返回其起始位置的索引；如果未找到，则返回 -1。
print(f"{name.find('jia')} - 方法: 查找子字符串")  # 打印: '2 - 方法: 查找子字符串'

# 分割字符串
print(f"{name.split('j')} - 方法: 分割字符串")  # 打印: "['yu', 'iahao'] - 方法: 分割字符串"

# 拼接字符串
print(f"{'_'.join(['yu', 'jiahao'])} - 方法: 拼接字符串")  # 打印: 'yu_jiahao - 方法: 拼接字符串'

# 检查前缀
print(f"{name.startswith('yu')} - 方法: 检查前缀")  # 打印: 'True - 方法: 检查前缀'

# 检查后缀
print(f"{name.endswith('hao')} - 方法: 检查后缀")  # 打印: 'True - 方法: 检查后缀'


# 使用for循环遍历
for i in name:
    print(f'使用for循环遍历:{i}')

# 使用while循环遍历
count = 0
while count < len(name):
    print(f'使用while循环遍历：{name[count]}')
    count = count + 1

# 字符串中的转义

my_string = "这是一个多行字符串。\n它可以跨越多行，\n但有时你需要使用转义字符来换行。"

print(my_string)
my_string = "Hello, World!"
new_string = my_string.replace("World", "Python")
print(new_string)


# 常规字符串中的反斜杠需要进行转义
s1 = "C:\\Users\\Alice\\Documents\\file.txt"
print(s1)

# 原始字符串中的反斜杠不需要进行转义
s2 = r"C:\Users\Alice\Documents\file.txt"
print(s2)

# 需要注意的是，原始字符串中的最后一个字符不能是反斜杠。如果你需要在字符串的末尾使用反斜杠，则需要在字符串中添加一个额外的反斜杠来转义它，或者在字符串的末尾添加一个空格。
s3 = r"C:\Users\Alice\Documents\file.txt\ "
print(s3)


# todo 其他方法：



# 检查是否全为字母
print(f"{name.isalpha()} - 方法: 检查是否全为字母")  # 打印: 'True - 方法: 检查是否全为字母'

# 检查是否全为数字
print(f"{name.isdigit()} - 方法: 检查是否全为数字")  # 打印: 'False - 方法: 检查是否全为数字'

# 检查是否全为字母或数字
print(f"{name.isalnum()} - 方法: 检查是否全为字母或数字")  # 打印: 'True - 方法: 检查是否全为字母或数字'

# 检查是否全为小写
print(f"{name.islower()} - 方法: 检查是否全为小写")  # 打印: 'True - 方法: 检查是否全为小写'

# 检查是否全为大写
print(f"{name.isupper()} - 方法: 检查是否全为大写")  # 打印: 'False - 方法: 检查是否全为大写'

# 检查是否全为空白字符
print(f"{name.isspace()} - 方法: 检查是否全为空白字符")  # 打印: 'False - 方法: 检查是否全为空白字符'

# 检查字符串是否为标题格式（每个单词首字母大写）
print(f"{name.istitle()} - 方法: 检查字符串是否为标题格式")  # 打印: 'False - 方法: 检查字符串是否为标题格式'

# 将字符串居中，并使用指定字符填充
print(f"{name.center(20, '*')} - 方法: 将字符串居中，并使用指定字符填充")  # 打印: '******yujiahao****** - 方法: 将字符串居中，并使用指定字符填充'

# 将字符串左对齐，并使用指定字符填充
print(f"{name.ljust(20, '*')} - 方法: 将字符串左对齐，并使用指定字符填充")  # 打印: 'yujiahao************ - 方法: 将字符串左对齐，并使用指定字符填充'

# 将字符串右对齐，并使用指定字符填充
print(f"{name.rjust(20, '*')} - 方法: 将字符串右对齐，并使用指定字符填充")  # 打印: '************yujiahao - 方法: 将字符串右对齐，并使用指定字符填充'

# 翻转字符串
print(f"{name[::-1]} - 方法: 翻转字符串")  # 打印: 'oahajiuY - 方法: 翻转字符串'

# 转换为字节对象
print(f"{name.encode()} - 方法: 转换为字节对象")  # 打印: "b'yujiahao' - 方法: 转换为字节对象"

# 计算子字符串出现的次数
print(f"{name.count('a')} - 方法: 计算子字符串出现的次数")  # 打印: '2 - 方法: 计算子字符串出现的次数'

# 查找子字符串最后一次出现的位置
print(f"{name.rfind('a')} - 方法: 查找子字符串最后一次出现的位置")  # 打印: '6 - 方法: 查找子字符串最后一次出现的位置'

# 将字符串转为大小写互换
print(f"{name.swapcase()} - 方法: 将字符串转为大小写互换")  # 打印: 'YUJIAHAO - 方法: 将字符串转为大小写互换'


# 检查字符串是否为有效的标识符
print(f"{name.isidentifier()} - 方法: 检查字符串是否为有效的标识符")  # 打印: 'True - 方法: 检查字符串是否为有效的标识符'

# 将字符串中的制表符替换为空格
tab_string = "Hello\tWorld"
print(f"{tab_string.expandtabs(4)} - 方法: 将字符串中的制表符替换为空格")  # 打印: 'Hello   World - 方法: 将字符串中的制表符替换为空格'

# 将字符串按指定宽度填充0
print(f"{name.zfill(10)} - 方法: 将字符串按指定宽度填充0")  # 打印: '0yujiahao - 方法: 将字符串按指定宽度填充0'

# 将字符串分割成三部分：分隔符前、分隔符、分隔符后
print(f"{name.partition('jia')} - 方法: 将字符串分割成三部分")  # 打印: "('yu', 'jia', 'hao') - 方法: 将字符串分割成三部分"

# 将字符串从右边分割成三部分：分隔符前、分隔符、分隔符后
print(f"{name.rpartition('jia')} - 方法: 将字符串从右边分割成三部分")  # 打印: "('yu', 'jia', 'hao') - 方法: 将字符串从右边分割成三部分"

# 以换行符为分隔符分割字符串，保留换行符
multi_line_string = "Hello\nWorld\nPython"
print(f"{multi_line_string.splitlines(True)} - 方法: 以换行符为分隔符分割字符串，保留换行符")  # 打印: "['Hello\n', 'World\n', 'Python'] - 方法: 以换行符为分隔符分割字符串，保留换行符"

# 以换行符为分隔符分割字符串，不保留换行符
print(f"{multi_line_string.splitlines(False)} - 方法: 以换行符为分隔符分割字符串，不保留换行符")  # 打印: "['Hello', 'World', 'Python'] - 方法: 以换行符为分隔符分割字符串，不保留换行符"

# 检查字符串是否只包含 ASCII 字符
ascii_string = "Hello"
non_ascii_string = "你好"
print(f"{ascii_string.isascii()} - 方法: 检查字符串是否只包含 ASCII 字符")  # 打印: 'True - 方法: 检查字符串是否只包含 ASCII 字符'
print(f"{non_ascii_string.isascii()} - 方法: 检查字符串是否只包含 ASCII 字符")  # 打印: 'False - 方法: 检查字符串是否只包含 ASCII 字符'

# 检查字符串是否只包含十进制字符
decimal_string = "12345"
non_decimal_string = "12345a"
print(f"{decimal_string.isdecimal()} - 方法: 检查字符串是否只包含十进制字符")  # 打印: 'True - 方法: 检查字符串是否只包含十进制字符'
print(f"{non_decimal_string.isdecimal()} - 方法: 检查字符串是否只包含十进制字符")  # 打印: 'False - 方法: 检查字符串是否只包含十进制字符'

# 检查字符串是否只包含数字字符
numeric_string = "12345"
non_numeric_string = "12345a"
print(f"{numeric_string.isnumeric()} - 方法: 检查字符串是否只包含数字字符")  # 打印: 'True - 方法: 检查字符串是否只包含数字字符'
print(f"{non_numeric_string.isnumeric()} - 方法: 检查字符串是否只包含数字字符")  # 打印: 'False - 方法: 检查字符串是否只包含数字字符'

# 检查字符串是否只包含可打印字符
printable_string = "Hello World!"
non_printable_string = "\x00\x01"
print(f"{printable_string.isprintable()} - 方法: 检查字符串是否只包含可打印字符")  # 打印: 'True - 方法: 检查字符串是否只包含可打印字符'
print(f"{non_printable_string.isprintable()} - 方法: 检查字符串是否只包含可打印字符")  # 打印: 'False - 方法: 检查字符串是否只包含可打印字符'

# 将字符串中的每个单词的首字母大写
sentence = "hello xi bei zhang xue you "
print(f"{sentence.title()} - 方法: 将字符串中的每个单词的首字母大写")  # 打印: 'Hello Xi Bei Zhang Xue You - 方法: 将字符串中的每个单词的首字母大写'

# 填充

name = "meet{},{},{}"
name1 = name.format("宇佳豪","西北","张学友")  # 按照位置顺序填充
print(name1)

name = "meet{0},{1},{2}"
name2 = name.format("张学友","西北","分豪")  # 按照下标填充
print(name2)

name = "meet{a},{c},{b}"
name3 = name.format(a="宇佳豪",b="张学友",c="西北") # 按照关键字填充
print(name3)